package com.ys.servers.points.service.impl;

import com.ys.servers.common.util.CommonUtils;
import com.ys.servers.points.dao.PointsTypeDao;
import com.ys.servers.points.dao.impl.PointsTypeDaoImpl;
import com.ys.servers.points.data.PointsType;
import com.ys.servers.points.service.PointsTypeService;
import io.vertx.core.AsyncResult;
import io.vertx.core.Future;
import io.vertx.core.Handler;
import io.vertx.core.json.JsonObject;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by taotao on 2017/5/8.
 */
public class PointsServiceImpl implements PointsTypeService {

    private PointsTypeDao pointsTypeDao;


    public PointsTypeDao getPointsTypeDao() {
        return pointsTypeDao;
    }

    public PointsTypeService setPointsTypeDao(PointsTypeDao pointsTypeDao) {
        this.pointsTypeDao = pointsTypeDao;
        return this;
    }

    public PointsServiceImpl() {
        pointsTypeDao = new PointsTypeDaoImpl();
    }

    @Override
    public PointsTypeService addPointsType(PointsType pointsType, Handler<AsyncResult<PointsType>> resultHandler) {
        getPointsTypeDao().getPointsType(pointsType.getId()).setHandler(existRes -> {
            if (CommonUtils.validAsyncResult(existRes)) {
                resultHandler.handle(existRes);
            } else {
                doSavePointsType(pointsType, resultHandler);
            }
        });

        return this;
    }

    private PointsTypeService doSavePointsType(PointsType pointsType, Handler<AsyncResult<PointsType>> resultHandler) {
        getPointsTypeDao().savePointsType(pointsType).setHandler(res -> {
            if (CommonUtils.validAsyncResult(res)) {
                getPointsTypeDao().addPointsTypeToRedisList(res.result());
            }
            resultHandler.handle(res);
        });
        return this;
    }

    @Override
    public PointsTypeService removePointsType(String id, Handler<AsyncResult<Boolean>> resultHandler) {
        getPointsTypeDao().getPointsType(id).setHandler(res -> {
            getPointsTypeDao().removePointsType(id).setHandler(resultHandler);
            if (CommonUtils.validAsyncResult(res)) {
                getPointsTypeDao().removePointsTypeFromRedisList(res.result());
            }
        });

        return this;
    }

    @Override
    public PointsTypeService restorePointsType(String id, Handler<AsyncResult<PointsType>> resultHandler) {
        getPointsTypeDao().restorePointsType(id).setHandler(res -> {
            if (CommonUtils.validAsyncResult(res)) {
                getPointsTypeDao().addPointsTypeToRedisList(res.result());
            }
            resultHandler.handle(res);
        });
        return this;
    }

    @Override
    public PointsTypeService getPointsType(String id, Handler<AsyncResult<PointsType>> resultHandler) {
        getPointsTypeDao().getPointsType(id).setHandler(resultHandler);
        return this;
    }

    @Override
    public PointsTypeService getAllPointsType(Handler<AsyncResult<List<PointsType>>> resultHandler) {
        getPointsTypeDao().getAllPointsType().setHandler(resultHandler);
        return this;
    }

    @Override
    public PointsTypeService updatePointsType(PointsType pointsType, Handler<AsyncResult<PointsType>> resultHandler) {
        String id = pointsType.getId();
        getPointsTypeDao().getPointsType(id).setHandler(res -> {
            if (CommonUtils.validAsyncResult(res)) {
                getPointsTypeDao().removePointsTypeFromRedisList(res.result()).setHandler(remRes -> {
                    doSavePointsType(pointsType, resultHandler);
                });
            } else {
                doSavePointsType(pointsType, resultHandler);
            }
        });
        return this;
    }

    @Override
    public PointsTypeService disablePointsType(String id, Handler<AsyncResult<PointsType>> resultHandler) {
        getPointsTypeDao().getPointsType(id).setHandler(res -> {
            if (CommonUtils.validAsyncResult(res)) {
                PointsType pointsType = res.result();
                getPointsTypeDao().removePointsTypeFromRedisList(pointsType).setHandler(remRes -> {
                    pointsType.setStatus(0);
                    doSavePointsType(pointsType, resultHandler);
                });
            } else {
                Future<PointsType> future = Future.future();
                future.complete(null);
                future.setHandler(resultHandler);
            }
        });
        return this;
    }

    @Override
    public PointsTypeService enablePointsType(String id, Handler<AsyncResult<PointsType>> resultHandler) {
        getPointsTypeDao().getPointsType(id).setHandler(res -> {
            if (CommonUtils.validAsyncResult(res)) {
                PointsType pointsType = res.result();
                if (pointsType.getStatus() != 1) {
                    getPointsTypeDao().removePointsTypeFromRedisList(pointsType).setHandler(remRes -> {
                        pointsType.setStatus(1);
                        doSavePointsType(pointsType, resultHandler);
                    });
                } else {
                    Future<PointsType> future = Future.future();
                    future.complete(pointsType);
                    future.setHandler(resultHandler);
                }
            } else {
                Future<PointsType> future = Future.future();
                future.complete(null);
                future.setHandler(resultHandler);
            }
        });
        return this;
    }

    @Override
    public PointsTypeService getAllPointsTypeDesc(Handler<AsyncResult<List<PointsTyeDesc>>> resultHandler) {

        Future<List<PointsTyeDesc>> result = Future.future();
        result.setHandler(resultHandler);
        List<PointsTyeDesc> resultList = new ArrayList<>();
        getPointsTypeDao().getAllPointsType().setHandler(allPointsTypeRes -> {
            if (CommonUtils.validAsyncResult(allPointsTypeRes)) {
                List<PointsType> allType = allPointsTypeRes.result();
                allType.stream().filter(oneType -> oneType.getStatus() == 1).forEach(oneType -> {
                    resultList.add(new PointsTyeDesc().setTitle(oneType.getLogDesc()).setDesc(oneType.getDesc()));
                });
            }
            result.complete(resultList);
        });
        return this;
    }

}
